import axios, { AxiosError, type AxiosInstance, type AxiosRequestConfig, type AxiosResponse, type InternalAxiosRequestConfig } from 'axios'
import { checkStatus } from './helper/checkStatus'
import { message } from 'antd'
import { store } from '../store'
import type { ResultData } from './interface'

const config = {
  baseURL: '', // 默认地址请求地址
  timeout: 10000, // 设置超时时间（10s）
  withCredentials: true, // 跨域时候允许携带凭证
}

class HttpService {
  service: AxiosInstance;

  constructor(config: AxiosRequestConfig) {
    this.service = axios.create(config)

    // 请求拦截器
    this.service.interceptors.request.use((config: InternalAxiosRequestConfig) => {
      const token = store.getState().global.token || window.localStorage.getItem('AppToken') || ''
      if (token) {
        config.headers.Authorization = `Bearer ${token}`
      }
      return config
    },
      (error) => {
        return Promise.reject(error)
      }
    )
    // 响应拦截器
    this.service.interceptors.response.use((response: AxiosResponse) => {
      const { data } = response;
      // 跳转到登录页面
      if (data.code === 401) {
        message.error('暂无权限，请重新登录')
        window.location.hash = '/login'
        return Promise.reject(data)
      }
      if (data.code !== 200) {
        message.error(data.msg)
        return Promise.reject(data)
      }
      return data
    },
      (error: AxiosError) => {
        const { response } = error;
        //根据响应的错误状态码，做不同的处理
        if (response) checkStatus(response.status)
        // 断网处理:可以跳转到断网页面
        if (!window.navigator.onLine) window.location.hash = '/500'
        return Promise.reject(error)
      }
    )
  }

  // 常用请求方法封装
  get<T>(url: string, params?: object, config = {}): Promise<ResultData<T>> {
    return this.service.get(url, { params, ...config })
  }

  post<T>(url: string, data?: object, config = {}): Promise<ResultData<T>> {
    return this.service.post(url, data, config)
  }

  put<T>(url: string, data?: object, config = {}): Promise<ResultData<T>> {
    return this.service.put(url, data, config)
  }

  delete<T>(url: string, data?: object, config = {}): Promise<ResultData<T>> {
    return this.service.delete(url, { data, ...config })
  }
}

export default new HttpService(config)